/*
 * Serveur.java
 */
package superchat;

import java.net.*;
import org.json.*;

/**
 * Classe serveur
 * @author georgesm
 */
class Serveur extends Thread {

    int port;
    ServerSocket ss;
    ClientList clients;

    /**
     * Constructeur du serveur
     * @param port Port de connexion
     */
    public Serveur(int port) {
        try {
            this.port = port;
            ss = new ServerSocket(port);
            clients = new ClientList();
        } catch (Exception ex) {
            System.out.println("Erreur lors de la création du serveur.");
        }
    }

    /**
     * Thread Serveur
     */
    @Override
    public void run() {
        boolean run = true;
        while (run) {
            try {
                Communication c = new Communication(ss.accept(), this);
                //clients.add(c);
                c.start();
            } catch (Exception ex) {
                run = false;
            }
        }
    }

    /**
     * Fonction appelée par la communication lors de la reception d'un message
     * @param com L'objet com qui a appelé la methode
     */
    void interpretMessage(Communication com) {
        try {
            int action = com.message.getInt("action");
            String message;
            switch (action) {
                case 0:
                    String pseudo = com.message.getString("pseudo");
                    if (clients.pseudoDisponible(pseudo)) {
                        clients.add(com, pseudo);
                        sendToAll(new JSONObject().put("action", 50).put("pseudos", clients.pseudos).toString());
                    } else {
                        com.out.writeUTF(new JSONObject().put("action", 400).toString());
                        com.socket.close();
                        com = null;
                    }
                    break;
                case 1:
                    message = filtreInsultes(com.message.getString("message"));
                    sendToAll(new JSONObject().put("action", 51).put("pseudo", clients.getPseudo(com)).put("message", message).toString());
                    break;
                case 2:
                    if(!clients.pseudoDisponible(com.message.getString("destinataire"))) {
                        String expediteur = clients.getPseudo(com);
                        String destinataire = com.message.getString("destinataire");
                        message = filtreInsultes(com.message.getString("message"));
                        JSONObject j = new JSONObject();
                        j.put("action", 52);
                        j.put("expediteur", expediteur);
                        j.put("message", message);
                        clients.getComByPseudo(destinataire).out.writeUTF(j.toString());
                    }
                    break;
                case 3:
                    if(!clients.pseudoDisponible(com.message.getString("destinataire"))) {
                        String expediteur = clients.getPseudo(com);
                        String destinataire = com.message.getString("destinataire");
                        String filename = com.message.getString("filename");
                        JSONObject j = new JSONObject();
                        j.put("action", 53);
                        j.put("expediteur", expediteur);
                        j.put("filename", filename);
                        clients.getComByPseudo(destinataire).out.writeUTF(j.toString());
                    }
                    break;
                case 4:
                    if(!clients.pseudoDisponible(com.message.getString("destinataire"))) {
                        String expediteur = clients.getPseudo(com);
                        String destinataire = com.message.getString("destinataire");
                        String filename = com.message.getString("filename");
                        JSONObject j = new JSONObject();
                        j.put("action", 54);
                        j.put("expediteur", expediteur);
                        j.put("filename", filename);
                        clients.getComByPseudo(destinataire).out.writeUTF(j.toString());
                    }
                    break;
                case 5:
                    if(!clients.pseudoDisponible(com.message.getString("destinataire"))) {
                        String expediteur = clients.getPseudo(com);
                        String destinataire = com.message.getString("destinataire");
                        JSONObject j = new JSONObject(com.message.toString());
                        j.remove("action");
                        j.remove("destinataire");
                        j.put("action", 55);
                        j.put("expediteur", expediteur);
                        clients.getComByPseudo(destinataire).out.writeUTF(j.toString());
                    }
                    break;
            }
        } catch (Exception ex) {
            System.out.println("Erreur interprétation message.");
        }
    }

    /**
     * Fonction de remplacement des insultes
     * @param str La chaine à modérer
     * @return La chaine modérée
     */
    public String filtreInsultes(String str) {
        return str.replaceAll("\\b(con|merde|crotte)\\b", "gentil");
    }
    
    /**
     * Fonction appelée par l'objet com lors d'une déconnexion
     * @param com L'objet Communication qui a appelé la méthode
     */
    public void disconnect(Communication com) {
        if(clients.hasCom(com)) {
            String pseudo = clients.getPseudo(com);
            clients.removeElement(com);
        }
        try {
            sendToAll(new JSONObject().put("action", 50).put("pseudos", clients.pseudos).toString());
        } catch (Exception e) {
            System.out.println("Erreur lors de la déconnexion");
        }

    }

    /**
     * Fonction d'envoi de message à tous les clients
     * @param message Message à envoyer
     */
    private void sendToAll(String message) {
        try {
            for (Communication client : clients) {
                client.out.writeUTF(message);
            }
        } catch (Exception ex) {
            System.out.println("Erreur lors de l'envoi du message à tout le monde.");
        }
    }
}
